﻿using System;
using System.Collections.Generic;
using CoreEx.Services;
using LinFu.IoC;
using LinFu.IoC.Interfaces;
using LinFu.Proxy.Interfaces;

namespace CoreEx.Common.Proxy
{
    /// <summary>
    /// Extends the <see cref="IProxyFactory"/> interface.
    /// </summary>
    public static class IProxyFactoryExtensions
    {
        private static readonly IServiceContainer _serviceContainer;


        static IProxyFactoryExtensions()
        {
            _serviceContainer = ServiceLocator.Container;
        }

        /// <summary>
        /// Creates a proxy type using the given
        /// <paramref name="baseType"/> as the base class
        /// and ensures that the proxy type implements the given
        /// interface types.
        /// </summary>
        /// <param name="proxyFactory">The <see cref="IProxyFactory"/> instance that will be used to generate the proxy type.</param>
        /// <param name="baseType">The base class from which the proxy type will be derived.</param>
        /// <param name="baseInterfaces">The list of interfaces that the proxy will implement.</param>
        /// <param name="interceptor">The <see cref="IConstructorInterceptor"/> instance that will be used to intercept 
        /// call to the constructor of the proxy type.</param>
        /// <remarks>
        /// This method can also be used to make modification to the proxy type during type construction.
        /// Implement the <see cref="ITypeModifier"/> and/or <see cref="IMethodModifier"/> interfaces to get notified
        /// during the type construct process.        
        /// </remarks>        
        /// <returns>A forwarding proxy.</returns>
        public static Type CreateProxyType(this IProxyFactory proxyFactory, Type baseType,
                                           IEnumerable<Type> baseInterfaces, IConstructorInterceptor interceptor)
        {
            return _serviceContainer.GetService<IDynamicProxyFactory>().CreateProxyType(proxyFactory, baseType,
                                                                                        baseInterfaces, interceptor);
        }
    }
}